<!--
/**
 * @package documentation
 * @copyright Copyright 2003-2006 Zen Cart Development Team
 * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
 * @version $Id: product_types_readme.html 3273 2006-03-27 16:48:29Z drbyte $
 */
//-->
<html>
	<head>
		<title>Zen Cart v1.2 商品类型介绍</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
		<meta name="author" content="Ian Wilson &amp; Kim Elliott" />
		<meta name="copyright" content="2004, 2007" />
	</head>

<style type="text/css">
<!--
body, table{ font-family:Verdana, Arial, Helvetica, sans-serif; font-size:14px; }
table.intro {border-color:C96E29; }
td.intro{background-color:#EEEEEE ; border-color:5778ce; font-size:14px; }
td.plainbox, div.callout {border: 1px dashed; border-color: C96E29; margin:5 40 5 40;}
.heading {background-color:5778CE; font-weight:bold; font-size:14px;	width: 100%; }

.title1 {color:C96E29; font-weight:bold; font-size:22px; }
.title2 {color:C96E29; font-weight:bold; font-size:13px; }
.small {font-size:10px ;}
.error {color:FF0000; }
.filename {font-family: mono, "Courier New", Courier ; font-size:14px; color: c96e29;}
.pseudolink {text-decoration:underline; color:5778CE;}
h1.intro { color: #ffffff; border:1px solid #aca893; background-color: #c96e29;  font-size: 22px;   padding: 4px;}
h1 { color: #ffffff;    border:1px solid #aca893;   background-color: #5778ce;   font-size: 20px;   padding: 4px;}
h2 { color: #c96e29; 	font-size: 18px;}
h3 { color: #5778ce;	font-size: 16px; margin-bottom:0px;}
h4 { color: #c96e29;	font-size: 14px;}


-->
</style>

<h1>Zen Cart v1.2 商品类型介绍</h1>
<h2>1. 简介</h2>
<p>一个经常提到的问题是，如何将不同类的商品按不同的风格显示。<br>
例如，音乐类商品和园艺类商品要保存和显示不同的内容。</p>
<p>以前Zen Cart&trade;网上商店用户只能修改代码实现。商品类型系统用于解决这个问题。</p>
<p>下面的简要说明，将使用v1.2版本中的音乐商品类型作为例子。具体实现，还要根据自己的需求来做调整。</p>
<p>本文将尽量说明原理，如有疑问，请到<a href="http://www.zen-cart.cn" target="_blank">www.zen-cart.cn论坛</a>上提出<br>
</p>
<h2>2. 数据库设计</h2>
<p>商品类型系统(PTS)使用Zen Cart的基本数据表和可选数据表。基本数据表包括:</p>
<p>PRODUCT_TYPES<br>
PRODUCT_TYPE_LAYOUT<br>
GET_TERMS_TO_FILTER</p>
<h3>PRODUCT_TYPES 数据表</h3>
<p>_PRODUCT_TYPES 数据表用于记录当前安装的商品类型的基本信息。包含以下8个字段</p>
<p>type_id<br>

type_name<br>
type_handler<br>
type_master_type<br>
allow_add_to_cart<br>
default_image<br>
date_added<br>
last_modified<br>
</p>
<p> <span class="heading">type_id</span> 是自动增值字段，PTS用于和商品类型的其它数据表关联。</p>
<p> <span class="heading">type_name</span> 用户定义字段，尽量采用开发小组使用的命名规则。例如在ZC 1.2中，使用“商品 - 普通”来定义标准商品，用“商品 - 音乐”来定义音乐CD的商品类型。还有“文档 - 普通”来定义文档的基本外观，以及“文档 - 商品”来定义用于出售的文档。这些名称位于管理商品页面的下拉菜单中。</p>
<p> <span class="heading">type_handler</span> 用户定义字段，用于定义指向商品类型代码的地址。最好定义成类似type_name字段。例如，如果type_name字段为商品-音乐，那么type_handler就为product_music。为了跨平台兼容，type_handler要使用小写字母。</p>
<p> <span class="heading">type_master_type</span> 用于将商品类型连接在一起。主要为了用不同的边框来显示特定商品类型的分类目录。例如，文档类型链接在一起，这样，可以建立一个边框，仅用来显示所有的文档类目录。</p>
<p> <span class="heading">allow_add_to_cart</span>. 该字段指定仅用于显示的商品类型，该类商品不能添加到购物车。基本的“文档”类型就是个例子。</p>
<p> <span class="heading">default_image</span> 保留字段。</p>
<p> <span class="heading">date_added/last_modified</span> 仅用于内部编码。</p>
<p>&nbsp;</p>
<h3>PRODUCT_TYPE_LAYOUT 数据表</h3>
<p> Zen Cart可以在管理页面下，设置商品信息页面上显示的字段，这部分信息保存在CONFIGURATION数据表。由于不同商品类型含不同信息，所以我们使用另一个数据表。</p>
<p>该数据表类似configuration表，含以下字段</p>
<p>configuration_id<br>
configuration_title<br>
configuration_key<br>
configuration_value<br>
configuration_description<br>
product_type_id<br>
sort_order<br>
last_modified<br>
date_added<br>
use_function<br>
set_function</p>
<p>下面是音乐类商品的一个例子：</p>
<p class="filename">INSERT INTO product_type_layout (configuration_title, configuration_key, configuration_value, configuration_description, product_type_id, sort_order, set_function, date_added) VALUES ('Show Record Company', 'SHOW_PRODUCT_MUSIC_INFO_RECORD_COMPANY', '1', 'Display Record Company on Product Info 0= off 1= on', '2', '4', 'zen_cfg_select_drop_down(array(array(\'id\'=&gt;\'1\', \'text\'=&gt;\'True\'), array(\'id\'=&gt;\'0\', \'text\'=&gt;\'False\')), ', now());</p>
<p>这样，管理员可以设定是否在商品信息页面显示唱片公司。当然，还需要修改音乐商品信息页面的代码：</p>
<p> <span class="filename">if (SHOW_PRODUCT_MUSIC_INFO_RECORD_COMPANY == '1') {<br>
?&gt;<br>
 &nbsp;&nbsp;&lt;tr&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;td class=&quot;main&quot; align=&quot;center&quot; colspan=&quot;2&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php echo sprintf(TEXT_RECORD_COMPANY_URL, zen_href_link(FILENAME_REDIRECT, 'action=url&amp;goto=' . <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;urlencode($products_record_company_url), 'NONSSL', true, false)); ?&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;<br>
&nbsp;&nbsp;&lt;/tr&gt;<br>
&lt;?php<br>
} // SHOW_PRODUCT_MUSIC_INFO_URL</span><br>
</p>
<p>这只是一个例子，参考商品信息页面的代码(参照PRODUCT_TYPE_LAYOUT数据表)<br>
</p>
<h3>GET_TERMS_TO_FILTER 数据表</h3>
<p>该表不算PTS的核心部分，但用于处理新的条件边框。
</p>
<p>条件边框根据一些变量来选择商品列表。</p>
<p>厂家边框就是一个例子，该边框根据商品厂家选择商品列表。</p>
<p>例如，显示所有Microsoft的商品。</p>
<p>音乐商品类型增加了两个条件边框，唱片公司和音乐类型</p>
<p>该表中只有一个字段：</p>
<p><span class="heading">get_term_name</span> - 这是条件边框返回的$_GET变量的名字，这将在后面的代码中说明。</p>
<p>&nbsp;</p>
<h2>3. 商店后台管理部分的代码</h2>
<p>旧版本中所有用于添加商品/分类的代码位于<span class="filename">admin/categories.php</span>文件。为了适应PST，该文件要分割。</p>
<p><span class="filename">admin/categories.php</span>现在仅用于显示和管理分类树，也含有添加新商品的按钮。访问新商品时，categories.php调用处理文件<span class="filename"> [product handler].php</span>，而<span class="heading">[product handler]</span>是product_types数据表中保存的名字。例如，音乐类型商品的处理文件为product_music.php。</p>
<p>该处理文件只是个框架，可以直接复制<span class="filename">product.php</span>为自定义的处理文件。记住还要建立一个相应的语言文件。</p>
<p>商品处理页面需要另外几个文件<br>
最重要的两个是:</p>
<p class="filename">admin/includes/modules/[handler_name]/collect_info.php<br>
admin/includes/modules/[handler_name]/preview_info.php</p>
<p>其中，<span class="heading">[handler name]</span>是product_types数据表中的type_handler字段。</p>
<p><strong>这两个文件在商品表中建立新记录，所以如果你的商品类型含有新字段/选项，这里是需要修改最多的地方。</strong></p>
<p><span class="heading">collect_info.php</span>含有输入商品细节的代码，例如</p>
<p>商品名称<br>
商品描述<br>
商品价格<br>
等等...</p>
<p><span class="heading">preview_info.php</span>用于将新建的商品数据写入数据库之前的预览。</p>
<p>在admin/includes/modules目录中，还有几个文件可以替代，也就是在admin/includes/modules/[handler name]/目录中，使用相同名字的文件, 视情况使用。</p>
<p>这些文件为:</p>
<p><span class="heading">update_product.php</span></p>
<p>该代码用于更新各个数据表，以将商品加入数据库。仅当你的商品类型需要在数据库中另外增加字段时，才需要替代该文件。</p>
<p>例如：音乐类型在单独数据表product_music_extra中保存类型类型、唱片公司，所以需要在update.php中添加代码，以保证collect_info.php中的信息能添加到数据表中。</p>
<p><span class="heading">copy_to_confirm.php</span></p>
<p>在复制商品时用到该代码。如果你的商品类型使用其它数据表保存资料，那么在这里添加代码，以保证数据复制到新商品中。</p>
<p>例如：音乐类型在这里添加代码，将products_music_extra数据表中的数据复制到新商品中。
</p>
<p><span class="heading">delete_product_confirm.php</span></p>
<p>该代码用于删除商品。在这里删除其它数据表中有关该商品类型的数据。
</p>
<p><span class="heading">move_product_confirm.php</span></p>
<p>该代码用于在分类间移动商品，通常不要替代该文件，因为移动仅修改product_id。当然也有可能需要修改。<br>
</p>
<h2>4. 商店前台的代码</h2>
<p>在分类中显示商品类型，要做的修改相对比较少。</p>
<p>总的来说，只要提供处理页面来显示商品信息。在新建商品信息页面前，先建立一个新目录<span class="heading">/includes/modules/pages/[handler name]_info</span></p>
<p>复制所有 includes/modules/pages/<strong>product_info</strong>/ 目录下的文件到 includes/modules/pages/[handler name]_info/ 目录。</p>
<p>通常该目录中需要修改的文件是 main_template_vars.php。 实际上，您不必修改这个文件。可以在<span class="heading">/includes/templates/YOUR_TEMPLATE/[handler name]_info/extra_main_template_vars目录</span>中新建脚本。该文件会被基本main_template_vars.php文件调用 (您还是要从product_info目录复制)，用于设定基本模板内容。(假设您在该文件中定义逻辑)。</p>
<p>例如：音乐类型在这里添加代码，用来从product_music_extra数据表中读取音乐类型、唱片公司等等信息。</p>
<p>然后需要为新商品类型的商品信息页面建立模板。该模板位于 includes/templates/template_default/templates，如果要和核心代码分开，就保存在 includes/templates/[your template]/templates。</p>
<p>模板文件必须命名为：</p>
<p><span class="heading">tpl_[handler name]_info_display.php</span>, 同样，[handler name]与product_types数据表中的type_handler相同。</p>
<p>当然要在模板中加入新商品类型的新添内容。</p>
<p>很重要的一点，在模板中，通常使用几个常量来定义是否显示某个元素。例如，在标准商品信息页面，SHOW_PRODUCT_INFO_QUANTITY 如果设置为1，将显示库存数量。这些常量保存在数据表product_type_layout中。<br />
最好是为该表中的每个商品类型建立不同的常量。例如，音乐类型使用SHOW_PRODUCT_MUSIC_INFO_QUANTITY替代了SHOW_PRODUCT_INFO_QUANTITY。这样，管理员可以给不同商品类型定制外观。</p>
<h2>5. 添加边框</h2>
<p>PTS的另外一个重要功能是条件边框可以选择商品列表。你在用厂家边框时可能就知道了，你可以列出指定厂家的商品。</p>
<p>音乐类型增加了两个条件边框：音乐类型和唱片公司。打开音乐类型边框的代码 <span class="filename"> includes/modules/sideboxes/music_genre.php</span> ，可以看到选择的音乐类型的ID会在url中通过$_GET变量调用music_genre_name。为了正确处理，需要自动记录这些条件。前面的数据库部分提到，你可以在<span class="heading">get_terms_to_filter</span>数据表中添加条件变量的名称。</p>
<h2>6. 已有的商品类型演示 </h2>
<p>可以参考一个现有的图书商品类型，作者是Justin K (jazzyjus)。</p>
<p>该图书商品类型可以从<a href="http://www.zen-cart.cn/modules/wfdownloads/singlefile.php?cid=8&lid=60" target="_blank">Zen Cart China</a>下载 </p>
<p>&nbsp;</p>
